<?php
class My_Model extends CI_Model {
	var	$_table			= '';
	var $_prkey				= '';
	var $_field				= array();
	var $_data				= array();

	var $_error				= '';

    function My_Model()
    {
        parent::__construct();
		$cacheFile = realpath(APPPATH).'/tmp/~table.'.$this->_table.'.php';
		if(file_exists($cacheFile)&&empty($this->_field)){
			$cache = include($cacheFile);
			$this->_field = $cache['fields'];
			if(isset($cache['pk']))$this->_prkey = $cache['pk'];
		}
		
    }

	/**
     * 初始化表结构
	 *
     * @access protected 
     * @return void
     * @throws KoExecption
     */
	function init(){
		if(!empty($this->_table)){
			$rQuery = $this->db->query("SHOW COLUMNS FROM {$this->_table}");
			$cache = array();
			$pks = array();
			foreach ($rQuery->result_array() as $field){
				if(is_object($field)) {
					$field	=	get_object_vars($field);
				}
				$fields[$field['Field']] = $field['Default'];
				if($field['Field']=='create_on'||$field['Field']=='update_on'){
					$fields[$field['Field']] = '';
				}
				
				if( strtolower($field['Key']) == 'pri' ){
					$pks[] = $field['Field'];
				}
			}
			if(count($pks)==1)$pks = $pks[0];
			$cache = array(
				'pk' => $pks,
				'fields'=> $fields,
			);
			$dbprefix = $this->db->dbprefix;
			$file = preg_replace("/^{$dbprefix}(\S+?)/", "\\1", $this->_table);
			$cacheFile = realpath(APPPATH).'/tmp/~table.'.$file.'.php';
			//if( is_writeable($cacheFile)){
				$content = 'return '.var_export( $cache,true ).";\n";
				$content  = "<?php\n".$content."\n?>";
				file_put_contents( $cacheFile,$content );
			//}
		}
	}

	function findByField($field){
		$query = $this->db->get_where($this->_table,$field);
		$rs = $query->result_array();
		return $rs;
	}

	function findByPk($id=null){
		$id = empty($id) ? $this->_data[$this->_prkey] : $id;
		if(!empty($id)){
			$where = array($this->_prkey=>$id);
			$query = $this->db->get_where($this->_table,$where);
			$rs = $query->result_array();
			return $rs[0];
		}
		return null;
	}

	function findByPks($prkey,$where=null){
		if(!is_array($prkey)){
			$prkey = array($prkey);
		}
		$this->db->where($where);
		$query = $this->db->where_in('id', $prkey)->get($this->_table);
		$rs = $query->result_array();
		return $rs;
	}

	function findAll($where=null){
		$query = $this->db->get_where($this->_table,$where);
		return $query->result_array();
	}
	
	
	function save($data){
		//update
		if(intval($data[$this->_prkey])>0){
			$data['update_on'] = time();
			$this->_data = $this->create($data,'update');
			if( $this->updateByPk($data[$this->_prkey]) ) return $data[$this->_prkey];
		}else{//insert
			$data['update_on'] = '';
			$data['creat_on'] = time();
			$this->_data = $this->create($data,'insert');
			return $this->insert();
		}
		return false;
	}

	function create($row,$type="insert"){
		foreach($this->_field as $_field=>$default){
			if(is_int($_field)){
				$_field = $default;
				$default = null;
			}
			if(isset($row[$_field])){
				$data[$_field] = $row[$_field];
			}else{
				if($type=='insert')$data[$_field] = $default;
			}
		}
		if(isset($this->_field['update_on'])) 
			$data['update_on'] = time();

		
		if(isset($this->_field['create_on'])&&$type=='insert'){
			$data['create_on'] = time();
		}
		return $data;
	}

	function insert(){
		if(!empty($this->_data)){
			return $this->db->insert($this->_table, $this->_data);
		}
		return false;
	}

	function update( $where = null ){
		if(!empty($this->_data)){
			return $this->db->update($this->_table, $this->_data, $where);
		}
		return false;
	}

	function updateByPk($prkey){
		if(!empty($this->_data)){
			return $this->db->update( $this->_table, $this->_data, array($this->_prkey => $prkey) );
		}
	}
	
	function removeByPks($prkey){
		if(!is_array($prkey)){
			$prkey = array($prkey);
		}
		return $this->db->where_in($this->_prkey, $prkey)->delete($this->_table);
	}

	function remove($where){
		return $this->db->where($where)->delete($this->_table);
	}
}